﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;

namespace FreeDream.Common.Helper
{
    public static class StringHelper
    {
        #region 1.0 获取AppSetting值
        /// <summary>
        /// 得到AppSetting值 
        /// </summary>
        /// <param name="values">appsetting Key</param>
        /// <returns></returns>
        public static string ValueOfAppSettings(this string values) => ConfigurationManager.AppSettings[values];

        /// <summary>
        /// 转换成int
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static int ValueOfIntAppSettings(this string values)
        {
            int intVal;
            int.TryParse(ConfigurationManager.AppSettings[values], out intVal);
            return intVal;
        }

        public static string ValueOfConnectionStrings(this string values) => ConfigurationManager.ConnectionStrings[values].ToString();

        #endregion

        #region 2.0 获取时间戳
        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public static string GetTimeStamp13(this System.DateTime time)
        {
            long ts = ConvertDateTimeToInt(time);
            return ts.ToString();
        }

        /// <summary>  
        /// 将c# DateTime时间格式转换为Unix时间戳格式  
        /// </summary>  
        /// <param name="time">时间</param>  
        /// <returns>long</returns>  
        public static long ConvertDateTimeToInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t;
        }
        #endregion

        #region 4 Md5
        /// <summary>
        /// 带补全
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Md5(this string str)
        {
            try
            {
                MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                var bytValue = Encoding.UTF8.GetBytes(str);
                var bytHash = md5.ComputeHash(bytValue);
                md5.Clear();
                string sTemp = "";
                foreach (var t in bytHash)
                {
                    sTemp += t.ToString("X").PadLeft(2, '0');
                }
                str = sTemp.ToLower();
            }
            catch (Exception)
            {
                //Console.WriteLine(e.Message);
            }

            return str;
        }

        #region 17.MD5加密
        /// <summary>
        /// x2
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static string GenerateMd5(this string txt)
        {
            using (MD5 mi = MD5.Create())
            {
                byte[] buffer = Encoding.Default.GetBytes(txt);
                //开始加密
                byte[] newBuffer = mi.ComputeHash(buffer);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < newBuffer.Length; i++)
                {
                    sb.Append(newBuffer[i].ToString("x2"));
                }
                return sb.ToString();
            }
        }

        public static string GenerateMd5Java(this string password)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(password), 0, password.Length);
            StringBuilder builder = new StringBuilder();
            foreach (byte b in res)
            {
                builder.Append(Convert.ToString(b, 16));
            }
            return builder.ToString();
        }
        #endregion

        #endregion

        #region 5.0 URL统一编码
        /// <summary>
        /// /9j/转成 %2F%39%6A%2F
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string FullUrlEncode(this string str)
        {
            var bytes = System.Web.HttpUtility.UrlEncodeToBytes(str);
            return Encoding.UTF8.GetString(bytes);
        }
        /// <summary>
        /// /9j/转成 %2f9j%2f
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UrlEncode(this string str)
        {
            //return str;
            return System.Web.HttpUtility.UrlEncode(str, System.Text.Encoding.UTF8);
        }
        /// <summary>
        /// 对Url进行编码
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="encoding">字符编码</param>
        /// <param name="isUpper">编码字符是否转成大写,范例,"http://"转成"http%3A%2F%2F"</param>
        public static string UrlEncode(string url, Encoding encoding, bool isUpper = false)
        {
            var result = System.Web.HttpUtility.UrlEncode(url, encoding);
            if (!isUpper)
                return result;
            return GetUpperEncode(result);
        }
        /// <summary>
        /// 获取大写编码字符串
        /// </summary>
        private static string GetUpperEncode(string encode)
        {
            var result = new StringBuilder();
            int index = int.MinValue;
            for (int i = 0; i < encode.Length; i++)
            {
                string character = encode[i].ToString();
                if (character == "%")
                    index = i;
                if (i - index == 1 || i - index == 2)
                    character = character.ToUpper();
                result.Append(character);
            }
            return result.ToString();
        }
        /// <summary>
        /// UrlDecode
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UrlDecode(this string str)
        {
            return System.Web.HttpUtility.UrlDecode(str, System.Text.Encoding.UTF8);
        }
        #endregion

        #region 3.0身份证相关验证

        #region 1.0 是否身份证号码格式 s + bool IsIDCard(this string InputStr)
        /// <summary>
        /// 是否身份证号码格式
        /// </summary>
        /// <param name="InputStr"></param>
        /// <returns></returns>
        public static bool IsIDCard(this string InputStr)
        {
            if (InputStr.Length == 18)
            {
                bool check = CheckIDCard18(InputStr);
                return check;
            }
            else if (InputStr.Length == 15)
            {
                bool check = CheckIDCard15(InputStr);
                return check;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 2.0 身份证长度判断 s + bool CheckIDCard18(string Id)
        private static bool CheckIDCard18(string Id)
        {
            long n = 0;
            if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0').Replace('X', '0'), out n) == false)
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
            string[] Wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
            char[] Ai = Id.Remove(17).ToCharArray();
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString());
            }
            int y = -1;
            Math.DivRem(sum, 11, out y);
            if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())
            {
                return false;//校验码验证
            }
            return true;//符合GB11643-1999标准
        }

        private static bool CheckIDCard15(string Id)
        {
            long n = 0;
            if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            return true;//符合15位身份证标准
        }
        #endregion

        #region 3.0 根据身份证推算年纪 s +  int GetAgeFromIdCard(this string idCard)
        /// <summary>
        /// 根据身份证推算年纪
        /// </summary>
        /// <param name="idCard">idcard</param>
        /// <returns></returns>
        public static int GetAgeFromIdCard(this string idCard)
        {
            var age = -1;
            if (idCard.IsIDCard())
            {
                if (idCard.Length == 18)
                {
                    string birth = idCard.Substring(6, 8).Insert(6, "-").Insert(4, "-");
                    age = DateTime.Now.Year - Convert.ToDateTime(birth).Year;
                }
                if (idCard.Length == 15)
                {
                    string birth = idCard.Substring(6, 6).Insert(4, "-").Insert(2, "-");
                    age = DateTime.Now.Year - Convert.ToDateTime(birth).Year;
                }
            }
            return age;
        }
        #endregion

        #region 4.0 通过身份证计算性别
        /// <summary>
        /// 计算性别
        /// </summary>
        /// <param name="identityCard"></param>
        /// <returns></returns>
        public static string GetSexByIdCard(this string identityCard)
        {
            string strSex = string.Empty;
            string returnSex = string.Empty;
            if (identityCard.IsIDCard())
            {
                if (identityCard.Length == 18)//处理18位的身份证号码从号码中得到生日和性别代码
                {
                    strSex = identityCard.Substring(14, 3);
                }
                if (identityCard.Length == 15)
                {
                    strSex = identityCard.Substring(12, 3);
                }
                if (int.Parse(strSex) % 2 == 0)//性别代码为偶数是女性奇数为男性
                {
                    returnSex = "女";
                }
                else
                {
                    returnSex = "男";
                }
            }
            return string.IsNullOrEmpty(returnSex) ? "男" : returnSex;
        }
        /// <summary>
        /// 计算性别代码
        /// </summary>
        /// <param name="identityCard"></param>
        /// <returns> "男" "1" :  "女":"2"</returns>
        public static string GetSexCodeByIdCard(this string identityCard)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(identityCard))
                {
                    return string.Empty;
                }
                string strSex = string.Empty;
                string returnSex = string.Empty;
                if (identityCard.IsIDCard())
                {
                    if (identityCard.Length == 18)//处理18位的身份证号码从号码中得到生日和性别代码
                    {
                        strSex = identityCard.Substring(14, 3);
                    }
                    if (identityCard.Length == 15)
                    {
                        strSex = identityCard.Substring(12, 3);
                    }
                    if (int.Parse(strSex) % 2 == 0)//性别代码为偶数是女性奇数为男性
                    {
                        returnSex = "2";
                    }
                    else
                    {
                        returnSex = "1";
                    }
                }
                return returnSex;
            }
            catch (Exception)
            {
                return string.Empty;
            }

        }

        #endregion

        #region 5.0根据身份证号码获取生日
        public static string GetBirthDayFormIdCard(this string idCard, string splitStr = "-")
        {
            if (!IsIDCard(idCard)) { return ""; }
            string year = idCard.Substring(6, 4);
            string month = idCard.Substring(10, 2);
            string date = idCard.Substring(12, 2);
            string result = year + splitStr + month + splitStr + date;
            return result;
        }
        #endregion
        #endregion

        #region 4.0 json序列化

        public static string ToJson<T>(this T obj)
        {
            if (obj == null) return null;
            return JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
        }
        public static string ToJson2<T>(this T obj)
        {
            if (obj == null) return null;
            return JsonConvert.SerializeObject(obj);
        }
        public static string XmlToJson(this XmlNode xml)
        {
            return JsonConvert.SerializeXmlNode(xml, Newtonsoft.Json.Formatting.Indented);
        }
        public static T JsonToObject<T>(this string str)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                return default;
            }
            return JsonConvert.DeserializeObject<T>(str);
        }

        public static string GetTimeStamp(this DateTime nowTime)
        {
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            //DateTime nowTime = DateTime.Now;
            long unixTime = (long)System.Math.Round((nowTime - startTime).TotalMilliseconds, MidpointRounding.AwayFromZero);
            return unixTime.ToString();
        }

        public static string ReturnSex(this string xb)
        {
            if (xb.Contains("男") || xb.Contains("女"))
            {
                return xb;
            }
            if (xb.Contains("1") || xb.Contains("2"))
            {
                xb = xb == "1" ? "男" : "女";
            }
            return xb;
        }
        #endregion

        #region 5.0 字符拆分
        public static string SpiltMapKey(this string str)
        {
            string[] strarr = str.Split(new char[] { '/' }, StringSplitOptions.None);
            if (strarr.Length == 2)
            {
                return strarr[0];
            }
            return str;
        }

        public static DateTime GetDateByUsualDate(this string date)
        {
            //20190909
            string tosigneday = date.Substring(0, 4) + "-" +
                                date.Substring(4, 2) + "-" +
                                date.Substring(6, 2);
            return Convert.ToDateTime(tosigneday);
        }
        #endregion

        #region 10.0 获取当前主机IPv4地址
        /// <summary>
        /// 获取当前主机IPv4地址
        /// </summary>
        /// <returns></returns>
        public static string GetIpAddress()
        {
            string hostName = Dns.GetHostName();
            IPHostEntry IpEntry = Dns.GetHostEntry(hostName);
            for (int i = 0; i < IpEntry.AddressList.Length; i++)
            {
                //从IP地址列表中筛选出IPv4类型的IP地址
                //AddressFamily.InterNetwork表示此IP为IPv4,
                //AddressFamily.InterNetworkV6表示此地址为IPv6类型
                if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
                {
                    return IpEntry.AddressList[i].ToString();
                }
            }
            return "";
            //IPAddress localaddr = localhost.AddressList[0];
            //return localaddr.ToString();
        }
        #endregion

        #region 10.1 获取读到的第一个mac地址 
        /// <summary>
        /// 获取读到的第一个mac地址:E8-6A-64-83-AE-01
        /// </summary>
        /// <returns>获取到的mac地址</returns>
        public static string GetMacAddress()
        {
            string mac = string.Empty;
            var networkInterfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
            foreach (System.Net.NetworkInformation.NetworkInterface adapter in networkInterfaces)
            {
                mac = adapter.GetPhysicalAddress().ToString();
                if (!string.IsNullOrEmpty(mac))
                    break;
            }
            var sb = new StringBuilder();
            for (var i = 0; i < mac.Length; i++)
            {
                sb.Append(mac[i]);
                if (i % 2 == 1 && i < mac.Length - 1)
                {
                    sb.Append("-");
                }
            }
            return sb.ToString();
        }
        #endregion

        #region 13.0 根据证件号码获取证件种类
        /// <summary>
        /// 根据证件号码获取证件种类
        /// </summary>
        /// <param name="cardNumber"></param>
        /// <returns></returns>
        public static int GetCardType(this string cardNumber)
        {
            int cardType = 0;
            string pex = cardNumber.Substring(0, 1);
            if (pex == "E" || pex == "G")
            {
                cardType = 14;
            }
            else if (pex == "C" || pex == "W")
            {
                cardType = 21;
            }
            else if (pex == "T" || pex == "L")
            {
                cardType = 25;
            }
            else
            {
                cardType = 0;
            }
            return cardType;
        }
        #endregion

        #region 14.0 获取业务类型
        /// <summary>
        /// 获取业务类型
        /// </summary>
        /// <param name="strSllx"></param>
        /// <returns></returns>
        public static string GetYwlx(this string strSllx)
        {
            string result;
            if (strSllx.Contains("港澳"))
            {
                result = "港澳通行证";
            }
            else
            {
                if (strSllx.Contains("大陆居民"))
                {
                    result = "台湾通行证";
                }
                else
                {
                    result = "护照";
                }
            }
            return result;
        }

        #endregion

        #region 15.0 申请预约来源
        /// <summary>
        /// 申领类型转换
        /// </summary>
        /// <param name="xxly"></param>
        /// <returns></returns>
        public static string CallBackXxly(this string xxly)
        {
            var rxxly = "";
            switch (xxly)
            {
                //网上预约自助机25
                case "15":
                    rxxly = "25";
                    break;
                //国家移民局APP自助机29
                case "99":
                    rxxly = "29";
                    break;
                //国家移民局互联网服务平台自助机28
                case "98":
                    rxxly = "28";
                    break;
                //国家移民局支付宝小程序自助机27
                case "97":
                    rxxly = "27";
                    break;
                //国家移民局微信小程序自助机26
                case "96":
                    rxxly = "26";
                    break;
                default:
                    rxxly = "10";
                    break;
            }
            return rxxly;
        }
        #endregion

        #region 16.0 截取后四位对比
        /// <summary>
        /// 截取后四位是否相同
        /// </summary>
        /// <param name="str1"></param>
        /// <param name="str2"></param>
        /// <returns></returns>
        public static bool CompleteStrLastFor(this string str1, string str2)
        {
            if (str1.Length > 4)
            {
                var str3 = str1.Substring(str1.Length - 4, 4);
                return str3 == str2;
            }
            return false;
        }
        #endregion

        #region 18.0 unix 时间戳转换为时间
        public static DateTime ConvertToDateTime(this string timestamp)
        {
            DateTime time = DateTime.MinValue;
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            if (timestamp.Length == 10)        //精确到秒
            {
                time = startTime.AddSeconds(double.Parse(timestamp));
            }
            else if (timestamp.Length == 13)   //精确到毫秒
            {
                time = startTime.AddMilliseconds(double.Parse(timestamp));
            }
            return time;
        }
        #endregion

        #region 19.0 ContentType和文件名转换
        /// <summary>
        ///  根据文件名获取http 传输ContentType
        /// </summary>
        /// <param name="fileName">.png</param>
        /// <returns></returns>
        public static string GetContentTypeByFileName(this string fileName)
        {
            return System.Web.MimeMapping.GetMimeMapping(fileName);
        }
        #endregion 

        #region 20.0 判断字符串是否是base64
        public static bool IsBase64String(this string s)
        {
            s = s.Trim().Replace("\r\n", "");
            s = s.Trim().Replace("\r", "");
            s = s.Trim().Replace("\n", "");
            return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);

        }
        /// <summary>
        /// 去掉回车换行
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string Base64StringFormat(this string s)
        {
            s = s.Trim().Replace("\r\n", "");
            s = s.Trim().Replace("\r", "");
            s = s.Trim().Replace("\n", "");
            return s;

        }
        #endregion 
    }
}
